package com.apobates.forum.toro.template.strategy;

import com.apobates.forum.toro.BatchQueryFace;
import com.apobates.forum.toro.template.TemplateExpression;
import com.apobates.forum.toro.template.TemplateStatements;
import com.apobates.forum.toro.utils.BeanHelper;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.stream.Collectors;

public class TemplateSerialBatchStrategy<E,T> extends AbstractTemplateStrategy implements TemplateBatchStrategy<E,T>{
    private final static Logger logger = LoggerFactory.getLogger(TemplateSerialBatchStrategy.class);
    @Override
    public Collection<E> apply(
            Class<E> targetObjClass,
            Collection<T> basicInsSet,
            List<TemplateStatements> statements,
            Map<String, BatchQueryFace> queries) {
        // 不同group name下的查询参数
        // key = group name, value=参数值,1,2,3,4
        Map<String, Collection<?>> queryArgMap = new HashMap<>();
        Map<String, Set<TemplateExpression>> argsMap = new HashMap<>();
        Map<String, Pair<String,String>> joinAttrMap = new HashMap<>();
        for(TemplateStatements ts : statements){
            Set<String> argVal = basicInsSet.stream().map(ele -> BeanHelper.getAttrVal(ele, ts.getJoinAttr()).toString()).collect(Collectors.toSet());
            queryArgMap.put(ts.getNames(), queries.get(ts.getNames()).query(argVal));
            argsMap.put(ts.getNames(), ts.getArguments());
            joinAttrMap.put(ts.getNames(), Pair.of(ts.getJoinAttr(), ts.getLinkAttr()));
        }

        // 最终的结果集
        List<E> data = new ArrayList<>();
        // 获取查询结果
        for (T ins : basicInsSet) {
            E tmp = BeanHelper.buildProxyInstance(targetObjClass, ins);
            if (null == tmp) {
                logger.debug(String.format("[Template][Batch]计算%s类型对象失败", tmp.getClass().getSimpleName()));
                continue;
            }
            // 给tmp赋值聚合属性值
            Set<String> groupNameSet = argsMap.keySet();
            for(String groupName : groupNameSet) {
                setMultiAttrVal(
                        tmp,
                        ins,
                        joinAttrMap.get(groupName).getLeft(),
                        joinAttrMap.get(groupName).getRight(),
                        groupName,
                        queryArgMap.get(groupName),
                        argsMap.get(groupName));
            }
            data.add(tmp);
        }
        return data;
    }

    @Override
    protected String getSentinel() {
        return "Batch";
    }
}
